#ifndef __DEFS_H__
#define __DEFS_H__


// Woooo magia! (bit field de un solo bit)
typedef struct _bit{
						unsigned int b:1;
} bit;


typedef struct {
            unsigned char simbolo;
            unsigned int apariciones;
            unsigned  int valido;           //indica si el valor almacenado en simbolo es valido
            void *padre ;
            void *izq;
            void *der ;
}__attribute__(( __packed__ )) nodo_arbol_t;


typedef struct {
            nodo_arbol_t *nodo_arbol ;
            void *sig;
} __attribute__(( __packed__ )) nodo_lista_t ;


typedef struct {
            unsigned int codigo;
            unsigned int codigo_rev;
            unsigned int long_codigo;
            unsigned int valido;       //indica si la informacion almacenada es valida                                                                    ´
} __attribute__ ((__packed__ )) codigo_t ;


typedef struct {
            unsigned int tam_original;
            unsigned int long_codificacion;
            unsigned int cant_codigos;
            unsigned int offset_codificacion;
} __attribute__ ((__packed__)) oc2_header_t;


typedef struct {
            unsigned char simbolo;
            unsigned int codigo;
            unsigned int long_codigo;
} __attribute__ (( __packed__ )) codificacion_t ;


extern
 int comprimir_archivo (
		const char *nomb_arch_entrada,
		const char *nomb_arch_salida );

extern
 int descomprimir_archivo (
		const char *nomb_arch_entrada,
		const char *nomb_arch_salida );

 extern 
int comprimir_buffer ( unsigned char *scr_buf, unsigned int scr_size,
		unsigned char **dst_buf, unsigned int *ptr_dst_size,
		codigo_t **tabla_codigos, unsigned int *long_codificacion );

 extern
 unsigned int *generar_tabla_apariciones ( unsigned char *buf,
		unsigned int size );

 extern
 codigo_t *generar_tabla_codigos ( unsigned int *tabla_apariciones );

extern
void crear_lista_huffman ( unsigned int *tabla_apariciones,
		nodo_lista_t **l, nodo_arbol_t **indices_nodos_simbolos );

extern
void lista_insertar_ordenado( nodo_lista_t **l, nodo_lista_t *n);

extern
 void crear_arbol_huffman ( nodo_lista_t **l, nodo_arbol_t **a );

extern
 void lista_obtener_primero ( nodo_lista_t **l, nodo_lista_t **n ); 

extern
 int generar_codigo ( nodo_arbol_t *a, nodo_arbol_t *h, codigo_t *c );

 extern
int generar_codificacion ( unsigned char *src_buf, unsigned int src_size,
		unsigned char *dst_buf, unsigned int dst_size, codigo_t *tabla_codigos );

 extern 
int calcular_longitud_codificacion ( unsigned int *tabla_apariciones,
		codigo_t *tabla_codigo );

extern
 int cargar_tabla_codigo_desde_buffer ( unsigned char * buf,
		unsigned int size, codigo_t **tabla_codigo );

extern
 int descomprimir_buffer ( unsigned char *src_buf,
		unsigned int long_codificacion, unsigned char *dst_buf,
		unsigned int dst_size, codigo_t *tabla_codigos );

extern
 int cargar_arbol_huffman(codigo_t *tabla_codigos, nodo_arbol_t **a );
 
//Auxiliares
extern
 void borrar_arbol (nodo_arbol_t* a);

#endif
